<template>
  <base-breadcrumb :title="$route.meta.title">
    <!-- 质量亮点管理 -->
    <div id="base-breadcrumb" style="position: relative; overflow: hidden">
      <!-- 搜索 -->
      <searchData
        :searchData="searchArr"
        @autoBranchSelected="autoBranchSelected"
        @autoSelected="autoSelected"
        @search="
          (e) => {
            ids = []
            exportLists = []
            search(e)
          }
        "
        @reset="handleReset"
      ></searchData>
      <!-- 表格 -->
      <a-card :bordered="false">
        <!-- <title-name :title="$route.meta.title"></title-name> -->
        <div class="mb12">
          <a-button type="primary" v-btnPermission="'qm_005_add_01'" icon="plus" @click="handleManage(2)"
            >新增质量亮点</a-button
          >
          <!-- <a-button v-btnPermission="'qm_005_add_01'" class="ml12" type="primary" icon="plus" @click="handleManage(2)">选中为质量月报亮点</a-button> -->
          <a-button
            v-btnPermission="'qm_005_bat_09'"
            :loading="exportLoading[0]"
            :disabled="!ids.length"
            class="ml12"
            type="primary"
            icon="download"
            @click="handleExport(false)"
            >选中导出{{ ids.length ? `（${ids.length}条）` : '' }}</a-button
          >
          <a-button
            v-btnPermission="'qm_005_all_10'"
            :loading="exportLoading[1]"
            :disabled="!highlightLevel"
            class="ml12"
            type="primary"
            icon="cloud-download"
            @click="handleExport(true)"
            >{{ exportLoading[1] ? `已导出${progress}%` : '全部导出' }}</a-button
          >
        </div>
        <!-- 统计汇总 -->
        <AuditSummary title="质量亮点" :form="queryParam" :loadCount="loadCount" :api="api" :init="false" :countList="countList" />
        <a-spin :spinning="spinning" tip="组织等级加载中..." style="width: 100%">
          <!-- 组织等级选项卡 -->
          <a-tabs
            v-if="tabs.length > 0"
            v-model="highlightLevel"
            @change="
              (e) => {
                highlightLevel = e
                search()
              }
            "
          >
            <!-- 组织等级列表 -->
            <a-tab-pane v-for="item in tabs" :key="item.id">
              <div slot="tab">
                {{ item.name }}
              </div>
              <slot />
            </a-tab-pane>
          </a-tabs>
          <div v-if="tabs.length == 0 && !spinning" class="mb12" align="center" style="width: 100%">
            <b>暂无等级信息</b>
          </div>
        </a-spin>
        <a-spin :spinning="loading">
          <a-row :gutter="32">
            <a-col :span="8" v-for="item in list" :key="item.id">
              <a-card hoverable>
                <!-- @click.stop="handleManage(0, item)" -->
                <video v-if="isTypeVideo(item.fileArrays[0])" width="100%" height="290" controls  :src="$fileUrl(item.fileArrays[0])"></video>
                <img v-else class="cover-img" slot="cover" :alt="item.fileName" :src="$fileUrl(item.fileArrays[0])" />
                <a-card-meta>
                  <div slot="description" class="title">
                    {{ item.highlightDescription }}
                  </div>
                </a-card-meta>
                <template slot="actions" class="ant-card-actions">
                  <a-button type="link" v-btnPermission="'qm_005_loo_04'" @click.stop="handleManage(0, item)"
                    >查看</a-button
                  >
                  <!-- 分级操作，只能编辑和删除自己层级的数据 -->
                  <template v-if="highlightCode === $currentPost().code && item.isEdit">
                    <a-button type="link" v-btnPermission="'qm_005_edi_02'" @click.stop="handleManage(1, item)"
                      >编辑</a-button
                    >
                    <!-- 若为公司人员登录，则可对公司级亮点删除；若为分公司人员登录，则可对分公司级亮点删除；若为项目部质量总监和项目总工，则可对项目级亮点删除 -->
                    <!-- &&
                      ($currentPost().code !== 'PD' ||
                      ($currentPost().code === 'PD' &&
                      ($currentPost().postCode === 'PMLZLJL' || $currentPost().postCode === 'PDLXMZG'))) -->
                    <a-button type="link" v-btnPermission="'qm_005_del_03'" @click.stop="handleRemove(item.id)"
                      >删除</a-button
                    >
                  </template>
                  <a-button
                    type="link"
                    v-btnPermission="'qm_005_pic_08'"
                    v-if="isCatch && item.isPick"
                    @click.stop="handleManage(3, item)"
                    >摘取</a-button
                  >
                  <!-- //暂不支持导出视频 -->
                  <a-checkbox
                    v-btnPermission="'qm_005_bat_09'"
                    v-if="!isTypeVideo(item.fileArrays[0])" 
                    :checked="ids.includes(item.id)"
                    @change="handleChange(item)"
                  ></a-checkbox>
                  <!-- <a-tooltip v-btnPermission="'qm_005_loo_04'" @click.stop="handleManage(0, item)">
                    <template slot="title">查看</template>
                    <a-icon key="eye" type="eye" />
                  </a-tooltip> -->
                  <!-- <template v-if="highlightCode === $currentPost().code && item.isEdit">
                    <a-tooltip v-btnPermission="'qm_005_edi_02'" @click.stop="handleManage(1, item)">
                      <template slot="title">编辑</template>
                      <a-icon key="edit" type="edit" />
                    </a-tooltip>
                    
                    <a-tooltip v-btnPermission="'qm_005_del_03'" @click.stop="handleRemove(item.id)">
                      <template slot="title">删除</template>
                      <a-icon key="delete" type="delete" />
                    </a-tooltip>
                  </template>
                  <a-tooltip
                    v-btnPermission="'qm_005_pic_08'"
                    v-if="isCatch && item.isPick"
                    @click.stop="handleManage(3, item)"
                  >
                    <template slot="title">摘取</template>
                    <a-icon key="copy" type="copy" />
                  </a-tooltip>
                  <a-checkbox
                    v-btnPermission="'qm_005_bat_09'"
                    :checked="ids.includes(item.id)"
                    @change="handleChange(item)"
                  ></a-checkbox> -->
                </template>
              </a-card>
            </a-col>
            <AEmpty v-if="!list.length" description="暂无数据" />
          </a-row>
          <a-pagination
            align="right"
            v-model="pageInfo.pageNo"
            show-size-changer
            :page-size.sync="pageInfo.pageSize"
            :show-total="(total) => `总共${total}条`"
            :total="pageInfo.total"
            :pageSizeOptions="['6', '9', '12', '15']"
            @change="loadData"
            @showSizeChange="loadData"
          />
        </a-spin>
      </a-card>
      <!-- <pre-view :previewImage="previewImage" :visible.sync="preVisible"></pre-view> -->
    </div>
  </base-breadcrumb>
</template>

<script>
import { Ellipsis } from '@/components' // 表格
import { highlight } from '@/api/quality/quality' // api
// import PreView from '@/components/PreView' // 图片预览
import SelectSubCompany from '@/components/Select/SelectSubCompany' // 分公司
import SelectProject from '@/components/Select/SelectProject' // 项目名称
import OrgTreeSelect from '@/components/OrgTreeSelect'
import Selector from '@/components/Select/Selector' // 公共下拉框
import AuditSummary from '@/views/quality/components/AuditSummary' // 统计汇总
import { typesLabel } from '@/api/quality/quality'
import { Empty } from 'ant-design-vue'
import JSZip from 'jszip'
import FileSaver from 'file-saver'
import SelectProjectType from '@/components/Select/SelectProjectType' // 工程类别
import SelectProjectStatus from '@/views/quality/components/SelectProjectStatus' // 项目状态

export default {
  name: 'a' + Date.now(),
  components: {
    Ellipsis,
    AuditSummary,
    AEmpty: Empty
  },
  data() {
    return {
      projectId: '',
      isSearchReset: false, // 重置所属单位 默认值
      queryParam: {
      }, // 查询参数
      pageInfo: {
        pageNo: 1,
        pageSize: 6,
        total: 0
      },
      ids: [], // 选中id集合
      exportLists: [], // 选中业务对象的集合
      exportAll: [], // 筛选过后的全部业务对象的集合
      zipList: [], // 导出的图片压缩包列表
      tabs: [], // tab列表
      highlightLevel: '', // 组织架构等级id
      currentHighlightLevel: '', // 当前岗位组织架构等级id
      exportLoading: { 0: false, 1: false },
      spinning: false, // tabs加载控件
      loading: false, // 列表加载控件
      list: [],
      countInfo: {}, //统计数据
      previewImage: [], // 预览图
      preVisible: false, // 预览图显隐控件
      api: highlight, // api
      loadCount: 0, // 汇总加载控件
      countList: [
        {
          title: '总数：',
          value: 'total'
        },
        {
          title: '项目级：',
          value: 'projectLevel'
        },
        {
          title: '分公司级：',
          value: 'branchLevel'
        },
        {
          title: '公司级：',
          value: 'companyLevel'
        }
      ], // 汇总列表
      isTypeVideoArr:['.mp4','.MP4','.RM','.rmvb','.3gp','.avi','.flv','.f4v','.mpg','.vob','.dat','.wmv','.asf','.mkv','.dv','.mov','.ts','.webm','.MOV','.MPV','.3GP'], //支持的视频格式

    }
  },
  created() {
    this.init();
    // 监听详情页返回刷新列表
    this.$bus.$on('handleRefresh' + this.$route.path, () => {
      this.search();
    })
  },
  computed: {
    searchArr() {
      return [
        // 搜索框
        {
          name: '所属单位',
          valueKey: 'searchQuery',
          type: OrgTreeSelect,
          attrs: {
            defaultSearchValue: this.$currentPost().code === 'PD' && this.$currentPost().id ? this.$currentPost().id : '',
            isClear: this.isSearchReset
          }
        },
        // {
        //   name: '分公司',
        //   type: SelectSubCompany,
        //   isDefaultSelected: this.$currentPost().code !== 'CO',
        //   autoSelected: false,
        //   getAll: true,
        //   valueKey: 'branchCompanyId'
        // },
        // {
        //   name: '项目名称',
        //   type: SelectProject,
        //   isDefaultSelected: this.$currentPost().code === 'PD',
        //   isSelf: false,
        //   valueKey: 'projectId'
        // },
        {
          name: '项目状态',
          type: SelectProjectStatus,
          valueKey: 'projectStatus',
        },
        {
          name: '工程类别',
          type: SelectProjectType,
          // maxTagCount: 2,
          // mode: 'multiple',
          valueKey: 'constructionTypeIds',
          showStop:false
          // currentRender(e) {
          //   return e?.length ? e.join() : e
          // }
        },
        // {
        //   name: '质量检查编号',
        //   type: 'input',
        //   value: 'checkNumber',
        // },
        {
          name: '亮点分类',
          type: Selector,
          valueKey: 'highlightType',
          selectType: '8'
        },
        // {
        //   name: '检查类型',
        //   valueKey: 'checkType',
        //   type: Selector,
        //   selectType: '0',
        //   attr: {
        //     code: 1
        //   }
        // },
        // {
        //   name: '亮点等级',
        //   valueKey: 'highlightLevel',
        //   type: Selector,
        //   selectType: '1',
        // },
        // {
        //   name: '施工时间',
        //   type: 'dateRange',
        //   value: 'constructionTime',
        //   attr: {
        //     rangeFormat: ['constructionTimeStart', 'constructionTimeEnd'],
        //   },
        // },
        {
          name: '分部分项',
          type: 'input',
          value: 'subItemId'
        },
        {
          name: '亮点名称',
          type: 'input',
          value: 'name'
        }
      ]
    },
    // 导出进度
    progress() {
      return this.exportAll.length
        ? (
            (this.zipList.length * 100) /
            this.exportAll.map((w) => (w.fileArrays ? w.fileArrays.length : 0)).reduce((total, e) => total + e)
          ).toFixed(2)
        : 0
    },
    // 1.若登录人员为公司的，则能对项目级和分公司级亮点进行摘取，摘取后流转到公司亮点列表中，被摘取的亮点依然在项目级或分公司级列表中，已摘取过的亮点不能再摘取；若更改了亮点描述，流转到公司列表中的亮点描述对应调整，被摘取的亮点描述不做调整；
    // 2.若登录人员为分公司的，则能对项目级亮点进行摘取，摘取后流转到分公司亮点列表中，被摘取的亮点依然在项目级列表中，已摘取过的亮点不能再摘取；若更改了亮点描述，流转到分公司列表中的亮点描述对应调整，被摘取的亮点描述不做调整；
    isCatch() {
      let code = this.$currentPost().code // 当前岗位组织层级
      let highlightCode = this.highlightCode // 当前列表组织层级
      return (
        code !== 'PD' &&
        ((code === 'CO' && highlightCode !== code) ||
          (code === 'BC' && highlightCode !== 'CO' && highlightCode !== 'BC'))
      )
    },
    // 组织架构等级code
    highlightCode() {
      return this.tabs.length ? ['PD', 'BC', 'CO'][this.tabs?.find((i) => i.id === this.highlightLevel)?.code - 1] : ''
    }
  },
  methods: {
    handleReset() {
      this.isSearchReset = true
    },
    init() {
      if (this.$currentPost().code === 'PD' && this.$currentPost().projectId) {
        this.projectId = this.$currentPost().projectId
      }
      typesLabel.getList({ type: '1' }).then((res) => {
        if (res.code === 200) {
          let level = { PD: '1', BC: '2', CO: '3' }[this.$currentPost().code] // 当前层级code
          // 映射tab列表
          this.tabs = res.data
          // 默认切换到当前层级tab
          this.highlightLevel = res.data?.find((item) => item.code === level)?.id
          this.currentHighlightLevel = res.data?.find((item) => item.code === level)?.id
          // console.log(this.$currentPost().code === 'BC', !this.queryParam.branchCompanyId)
          if (
            (this.$currentPost().code === 'BC') ||
            (this.$currentPost().code === 'PD' && this.$currentPost().projectId) ||
            this.$currentPost().code === 'CO'
          ) {
            let projectId = this.$currentPost().projectId
            if (projectId && this.$currentPost().code === 'PD') {
              this.search({projectId})
            } else {
              this.search()
            }
            
          }
        }
      })
    },
    // 分公司初始化
    autoBranchSelected(e) {
      this.$nextTick(() => {
        this.queryParam.branchCompanyId = e
        this.$currentPost().code === 'BC' && this.highlightLevel && this.search({ branchCompanyId: e })
      })
    },
    // 项目初始化
    autoSelected(e) {
      this.$nextTick(() => {
        this.queryParam.projectId = e
        this.$currentPost().code === 'PD' && this.highlightLevel && this.search({ projectId: e })
      })
    },
    /**
     * @description: 导出亮点
     * @param {*} isAll：是否导出全部
     */
    handleExport(isAll) {
      if (isAll) {
        const requestParameters = Object.assign(
          {},
          {
            highlightLevel: this.highlightLevel,
            needCount: false,
            // pageSize: this.pageInfo.total,
            // pageNo: 1,
            ...this.queryParam
          }
        )
        this.exportLoading[1] = true
        highlight
          .getList(requestParameters)
          .then((res) => {
            if (res.code === 200 && res.data?.length) {
              this.$nextTick(() => {
                this.exportAll = res.data
                console.log( this.exportAll,222)
                this.generateImgs(res.data)
              })
            } else {
              this.$message.warning('暂无数据可导出！')
              this.exportLoading[1] = false
            }
          })
          .catch(() => {
            this.exportLoading[1] = false
          })
      } else {
        this.exportLoading[0] = true
        this.exportAll = this.exportLists
        this.generateImgs(this.exportLists)
      }
    },
    /**
     * @description: base64转文件Blob
     * @param {String} dataurl:base64的url
     * @return {Blob}
     */
    dataURLtoBlob(dataurl) {
      var arr = dataurl.split(','),
        mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]),
        n = bstr.length,
        u8arr = new Uint8Array(n)
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n)
      }
      // console.log(mime)
      return new Blob([u8arr], { type: mime })
    },
    /**
     * @description: 把亮点信息生成图片
     * @param {*} datas：需要导出的亮点列表
     * @return {*}
     */
    generateImgs(datas) {
      // 遍历亮点列表
      for (let idx in datas) {
        let e = datas[idx]
        // 若存在图片，则遍历亮点图片
        if (e.fileArrays?.length) {
          for (let index in e.fileArrays) {
            let item = e.fileArrays[index] // 文件对象
            let src = this.$fileUrl(item) // 获取图片链接
            let canvas = document.createElement('canvas') // 新建canvas
            // 固定画布宽度和高度
            canvas.width = 3600
            let ctx = canvas.getContext('2d') // 获取画布2d对象
            let img = new Image() // 背景图对象
            // 映射背景图链接
            img.src = src
            // 背景图是异步，所以等背景图加载结束再开始绘图
            img.onload = () => {
              let imgHeight = (canvas.width * img.height) / img.width
              let highlightDescription = `亮点描述：${e.highlightDescription || '无'}` // 亮点描述
              let num = Math.ceil((ctx.measureText(highlightDescription).width * 16) / 10 / (canvas.width - 240)) // 计算亮点描述行数
              // console.log(num)
              canvas.height = imgHeight + 1120 + 300 * (num + 1) // 设置画布高度
              // 绘制白色背景
              ctx.fillStyle = '#fff'
              ctx.fillRect(0, 0, canvas.width, canvas.height)
              // 绘制二维码背景图
              ctx.drawImage(img, 0, 0, canvas.width, imgHeight)
              // 设置画笔颜色
              ctx.fillStyle = '#1793D4'
              // 设置字体样式
              ctx.font = 'bolder 160px "Times New Roman",Georgia,Serif'
              // 设置字体垂直居中
              ctx.textBaseline = 'middle'
              // 填充文字
              ctx.fillText(`亮点类型：${e.highlightType}`, 120, imgHeight + 220)
              ctx.fillText(`亮点名称：${e.highlightName}`, 120, imgHeight + 520)
              ctx.fillText(`分部分项：${e.subItemName || '无'}`, 120, imgHeight + 820)
              // 填充亮点描述文字
              var lineWidth = 0
              var canvasWidth = canvas.width - 240 //计算canvas的宽度
              var initHeight = imgHeight + 1120 //绘制字体距离canvas顶部初始的高度
              var lastSubStrIndex = 0 //每次开始截取的字符串的索引
              for (let i = 0; i < highlightDescription.length; i++) {
                lineWidth += ctx.measureText(highlightDescription[i]).width
                if (lineWidth > canvasWidth) {
                  ctx.fillText(highlightDescription.substring(lastSubStrIndex, i), 120, initHeight) //绘制截取部分
                  initHeight += 300 //30为字体的高度
                  lineWidth = 0
                  lastSubStrIndex = i
                }
                if (i == highlightDescription.length - 1) {
                  //绘制剩余部分
                  ctx.fillText(highlightDescription.substring(lastSubStrIndex, i + 1), 120, initHeight)
                }
              }
              let base64 = canvas.toDataURL('image/jpeg') // 图片的base64链接
              let dataURLtoBlob = this.dataURLtoBlob(base64) // base64转文件Blob
              // document.getElementById('base-breadcrumb').prepend(canvas)
              // 添加到图片压缩包列表
              this.zipList.push({
                name: `${e.highlightName}_${Number(idx) + 1}_${Number(index) + 1}`,
                url: dataURLtoBlob
              })
              this.downloadZip(datas, src, canvas, ctx, img)
            }
            img.onerror = (e) => {
              // console.log(e)
              // 添加一个空对象到图片压缩包列表
              this.zipList.push({})
              this.downloadZip(datas, src, canvas, ctx, img)
            }
          }
        }
      }
    },
    /**
     * @description: 下载压缩包
     * @param {*} datas：亮点列表，other：变量
     */
    downloadZip(datas, src, canvas, ctx, img) {
      // 当画完最后一个图时，把图片列表进行压缩打包
      if (this.zipList.length == datas.map((w) => w.fileArrays?.length || 0)?.reduce((total, e) => total + e)) {
        const zip = new JSZip()
        // 筛选出正常图片链接的图片
        let zipList = this.zipList.filter((i) => !!i.url)
        for (let item of zipList) {
          zip.file(item.name + '.jpg', item.url, { binary: true }) // 逐个添加文件，需要加后缀".jpg"
        }
        zipList.length &&
          zip.generateAsync({ type: 'blob' }).then((content) => {
            // 生成二进制流
            FileSaver.saveAs(content, '质量亮点列表') // 利用file-saver保存文件  自定义文件名
            // 清除变量缓存
            src = null
            canvas = null
            ctx = null
            img = null
            // 重置压缩包列表
            this.zipList = []
            // 重置业务列表
            this.exportAll = []
            // 取消加载loading
            this.exportLoading[0] = false
            this.exportLoading[1] = false
            this.$message.success('导出成功！')
          })
      }
    },
    /**
     * @description: 复选框切换选中状态
     * @param {*} item：当前业务对象
     */
    handleChange(item) {
      let id = item.id
      // 存在则删除，反之添加
      if (this.ids.includes(id)) {
        this.ids = this.ids.filter((i) => i !== id)
        this.exportLists = this.exportLists.filter((i) => i.id !== id)
      } else {
        this.ids.push(id)
        this.exportLists.push(item)
      }
    },
    /**
     * @description: 请求质量亮点列表
     */
    loadData() {
      // 组织架构等级必须存在
      if (!this.highlightLevel) {
        return
      }
      const requestParameters = Object.assign({}, this.pageInfo, {
        highlightLevel: this.highlightLevel,
        ...this.queryParam
      })
      this.loading = true
      highlight
        .postList(requestParameters)
        .then((res) => {
          this.loading = false
          if (res.code === 200) {
            this.list = res.data
            this.pageInfo.total = res.totalSize || 0
          }
        })
        .catch(() => {
          this.loading = false
        })
    },
    /**
     * 搜索
     */
    search(value) {
      if (value) {
        this.queryParam = value
      }
      this.loadData()
      this.loadCount++
    },
    /**
     * 操作栏
     */
    handleManage(e, record) {
      let query = {
        editModel: e,
        level: this.currentHighlightLevel
      }
      if (record) {
        query.id = record.id
      }
      if (e === 1 && this.$currentPost().code !== 'PD') {
        query.isCatch = 1
      }
      this.$router.push({
        name: 'highlightManageEdit',
        query
      })
    },
    /**
     * 删除草稿:api 请求api
     */
    handleRemove(id) {
      this.$confirm({
        title: '温馨提示',
        content: '请确定是否要删除该条数据？',
        onOk: () => {
          return highlight
            .delete({
              id
            })
            .then(() => {
              this.$message.success('删除成功！')
              // 初始化选中项
              this.search()
            })
        }
      })
    },
    isTypeVideo(fileArrays){
        let suffixName = fileArrays?.suffixName;
        let sTypeVideo = this.isTypeVideoArr.includes(suffixName);
        return sTypeVideo;
    }
  }
}
</script>

<style scoped>
.cover-img {
  object-fit: cover;
  height: 300px;
}
.title {
  text-overflow: -o-ellipsis-lastline;
  color: #666;
  overflow: hidden;
  height: 60px;
  text-overflow: ellipsis;
  display: -webkit-box;
  display: -moz-box;
  display: box;
  -webkit-box-orient: vertical;
  -moz-box-orient: vertical;
  box-orient: vertical;
  -webkit-line-clamp: 3;
  -moz-line-clamp: 3;
  line-clamp: 3;
}
</style>
